package fr.umlv.metadata;

import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.ArrayList;
import java.util.List;

import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import fr.umlv.authentication.SessionHandler;

// TODO: Auto-generated Javadoc
/**
 * The Class CategoryHandlerModel.
 */
public class CategoryHandlerModel implements TreeModel {
	
	/** The charset. */
	public static Charset charset = Charset.forName("UTF-8");
	
	/** The encoder. */
	public static CharsetEncoder encoder = charset.newEncoder();
	
	/** The decoder. */
	public static CharsetDecoder decoder = charset.newDecoder();
	
	/** The web service categ. */
	private static String webServiceCateg = "categories_tree";
	
	/** The categ param. */
	private static String categParam = "category";

	/** The category handler. */
	private static CategoryHandlerModel categoryHandler = null;
	
	/** The last calculated path. */
	private String lastCalculatedPath = "";
	
	/** The last result. */
	private List<Category> lastResult;
	
	/**
	 * Gets the single instance of CategoryHandlerModel.
	 *
	 * @return single instance of CategoryHandlerModel
	 */
	public static CategoryHandlerModel getInstance() {
		if (categoryHandler == null)
			categoryHandler = new CategoryHandlerModel();

		return categoryHandler;
	}
	
	/**
	 * Instantiates a new category handler model.
	 */
	public CategoryHandlerModel() {
		
	}
	
	/**
	 * The main method.
	 *
	 * @param args the arguments
	 */
	public static void main(String[] args) {
		CategoryHandlerModel han = CategoryHandlerModel.getInstance();
		han.getsubCategories(".");
	}
	
	/**
	 * Gets the sub categories.
	 *
	 * @param path the path
	 * @return the sub categories
	 */
	public List<Category> getsubCategories(String path){
		if(path == this.lastCalculatedPath){
			return lastResult;
		}
		this.lastCalculatedPath=path;
		this.lastResult=new ArrayList<Category>();

		Document categs = WebServiceUtils.getService(SessionHandler.getUrlWebServices() + webServiceCateg + "?" + categParam + "=" + path);
		Element racine = categs.getDocumentElement();
			
		NodeList children = racine.getChildNodes();
			
		for(int i = 0; i< children.getLength(); ++i){
			Node child = children.item(i);
			String categoryDisplayName  = child.getTextContent();
			String category_id = child.getAttributes().getNamedItem("id").getNodeValue();
			lastResult.add(new Category(path + "/" + "cm:" + categoryDisplayName, categoryDisplayName, category_id));
		}
		
		return this.lastResult;
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
	 */
	@Override
	public Object getChild(Object parent, int index) {
		Category categoryParent = (Category) parent;
		List<Category> result = this.getsubCategories(categoryParent.getPath());
		return result.get(index);
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
	 */
	@Override
	public int getChildCount(Object parent) {
		Category categoryParent = (Category) parent;
		List<Category> result = this.getsubCategories(categoryParent.getPath());
		return result.size();
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
	 */
	@Override
	public int getIndexOfChild(Object parent, Object child) {
		Category categoryParent = (Category) parent;
		List<Category> result = this.getsubCategories(categoryParent.getPath());
		return result.indexOf(child);
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#getRoot()
	 */
	@Override
	public Object getRoot() {
		return new Category(".", "All categories", "*");
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
	 */
	@Override
	public boolean isLeaf(Object node) {
		return false;
	}

	
	
	
	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
	 */
	@Override
	public void addTreeModelListener(TreeModelListener arg0) {
		
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
	 */
	@Override
	public void removeTreeModelListener(TreeModelListener arg0) {
		
	}

	/* (non-Javadoc)
	 * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)
	 */
	@Override
	public void valueForPathChanged(TreePath arg0, Object arg1) {
		
	}

}
